const Router = require('koa-router')
const uuid = require('uuid')
const { catchError, generateOk, check } = require('../../lib/check')
const { searchAccountById, searchAccount } = require('../../model/accounts')
const { setArticle, getAllArticles, searchArticle, editArticle } = require('../../model/articles')
const { reFreshToken } = require('./tool')

const article = new Router()

article.post('/add', async (ctx) => {
  try {
    const data = ctx.request.body
    check(!!data.content, 'Content_Is_Empty')
    check(!!data.title, 'Title_Is_Empty')
    check(!!data.author, 'Author_Is_Empty')
    check(!!(data.tabs.length), 'Tab_Is_Empty')
    const id = uuid.v4()
    const time = (new Date()).getTime().toString()
    const comments = []
    setArticle({ ...data, id: id, create_Ts: time, comments: comments, status: 1 })
    reFreshToken(ctx)
    ctx.body = generateOk({ ...data, id: id, create_Ts: time, comments: comments, status: 1 })
  } catch (e) {
    catchError(e, ctx)
  }
})

article.post('/get', async (ctx) => {
  try {
    const data = ctx.request.body
    let articles = getAllArticles().filter(article => article.status === 1)
    if (data.authorId) {
      articles = articles.filter(item => item.author === data.authorId)
    }
    if (data.tab) {
      articles = articles.filter(item => (item.tabs.filter(eachTab => eachTab.lable === data.tab)).length)
    }
    if (data.sort === 'time') {
      articles = articles.sort(function (a, b) { return (Number(b.create_Ts) - Number(a.create_Ts)) })
    } else if (data.sort === 'like') {
      articles = articles.sort(function (a, b) { return (b.like.length - a.like.length) })
    } else if (data.sort === 'save') {
      articles = articles.sort(function (a, b) { return (b.save.length - a.save.length) })
    }
    if (!!data.keyword) {
      articles = articles.filter(item => item.title.includes(data.keyword))
    }
    const total = articles.length
    const start = data.offset === undefined ? 0 : data.offset
    const size = data.limit === undefined ? 10 : data.limit
    const newArticles = articles.slice(start, start + size)
    const result = newArticles.map((item) => { return { ...item, author: searchAccountById(item.author) } })
    ctx.body = generateOk({ data: result, length: newArticles.length, total: total })
  } catch (e) {
    catchError(e, ctx)
  }
})

article.post("/good", async (ctx) => {
  try {
    let result
    const data = ctx.request.body
    check(!(data.articleId === undefined), "Article_UnPointOut")
    check(!(data.userId === undefined), "User_UnPointOut")
    check(((data.type === 'article') || (data.type === 'comment') || (data.type === 'reply')), 'Wrong_Type')
    const findArticle = searchArticle(data.articleId)
    check(!!findArticle, "No_Such_Article")
    check(!!searchAccountById(data.userId), "No_Such_User")
    if (data.type === 'article') {
      console.log(findArticle.like, data.userId)
      if (findArticle.like.findIndex(id => (id === data.userId)) !== -1) {
        result = { ...findArticle, like: findArticle.like.filter(id => id !== data.userId) }
      } else {
        result = { ...findArticle, like: [...findArticle.like, data.userId] }
      }
    } else {
      const findComment = findArticle.comments.find(comment => comment.id === data.commentId)
      check(findComment, 'No_Such_Comment')
      if (data.type === 'comment') {
        let resultComment
        if (findComment.like.findIndex(id => id === data.userId) !== -1) {
          resultComment = { ...findComment, like: findComment.like.filter(id => id !== data.userId) }
        } else {
          resultComment = { ...findComment, like: [...findComment.like, data.userId] }
        }
        findArticle.comments.splice(findArticle.comments.findIndex(comment => comment.id === findComment.id), 1, resultComment)
      } else {
        const findReply = findComment.reply.find(reply => reply.id === data.replyId)
        check(findReply, 'No_Such_Reply')
        let resultReply
        if (findReply.like.findIndex(id => id === data.userId) !== -1) {
          resultReply = { ...findReply, like: findReply.like.filter(id => id !== data.userId) }
        } else {
          resultReply = { ...findReply, like: [...findReply.like, data.userId] }
        }
        findComment.reply.splice(findComment.reply.findIndex(reply => reply.id === findReply.id), 1, resultReply)
        findArticle.comments.splice(findArticle.comments.findIndex(comment => comment.id === findComment.id), 1, { ...findComment })
      }
      result = { ...findArticle }
    }
    editArticle(result)
    // reFreshToken(ctx)
    ctx.body = generateOk(result)
  } catch (e) {
    catchError(e, ctx)
  }
})

article.post("/save", async (ctx) => {
  try {
    let result
    const data = ctx.request.body
    check(!(data.articleId === undefined), "Article_UnPointOut")
    check(!(data.userId === undefined), "User_UnPointOut")
    const findArticle = searchArticle(data.articleId)
    check(!!findArticle, "No_Such_Article")
    check(!!searchAccountById(data.userId), "No_Such_User")
    if (findArticle.save.findIndex(id => id === data.userId) !== -1) {
      result = { ...findArticle, save: findArticle.save.filter(id => id !== data.userId) }
    } else {
      result = { ...findArticle, save: [...findArticle.save, data.userId] }
    }
    editArticle(result)
    reFreshToken(ctx)
    ctx.body = generateOk(result)
  } catch (e) {
    catchError(e)
  }
})

article.post("/getDetail", async (ctx) => {
  try {
    const data = ctx.request.body
    check(!!data.articleId, "Params_Lost")
    const findArticle = searchArticle(data.articleId)
    check(!!findArticle, "No_Such_Article")
    const findAccount = searchAccountById(findArticle.author)
    const newComments = findArticle.comments.filter(comment => comment.status === 1).map((comment) => ({ ...comment, author: searchAccountById(comment.user), reply: comment.reply.filter(reply => reply.status === 1).map(item => ({ ...item, author: searchAccountById(item.user), targetUser: searchAccountById(item.targetUserId) })) }))
    ctx.body = generateOk({ ...findArticle, author: findAccount, comments: newComments })
  } catch (e) {
    catchError(e, ctx)
  }
})

article.post("/remove", async (ctx) => {
  try {
    const data = ctx.request.body
    check(data.type === 'article' || data.type === 'comment' || data.type === 'reply', 'Params_Lost')
    check(data.articleId, 'Params_Lost')
    check(data.userId, 'Params_Lost')
    const findArticle = searchArticle(data.articleId)
    check(!!findArticle, "No_Such_Article")
    if (data.type === 'article') {
      check(findArticle.author === data.userId, 'Not_Author_Done')
      editArticle({ ...findArticle, status: 0 })
      ctx.body = generateOk({ ...findArticle, status: 0 })
    } else {
      const findComment = findArticle.comments.find(comment => comment.id === data.commentId)
      check(findComment, 'No_Such_Comment')
      if (data.type === 'comment') {
        check(findComment.user === data.userId, 'Not_Author_Done')
        findArticle.comments.splice(findArticle.comments.findIndex(comment => comment.id === data.commentId), 1, { ...findComment, status: 0 })
      } else {
        const findReply = findComment.reply.find(reply => reply.id === data.replyId)
        check(findReply, 'No_Such_Comment')
        check(findReply.user === data.userId, 'Not_Author_Done')
        findArticle.comments.splice(findArticle.comments.findIndex(comment => comment.id === data.comentId), 1, findComment.reply.splice(findComment.reply.findIndex(reply => reply.id === data.replyId), 1, { ...findReply, status: 0 }))
      }
      editArticle(findArticle)
      ctx.body = generateOk(findArticle)
    }
  } catch (e) {
    catchError(e, ctx)
  }
})

article.post("/comment", async (ctx) => {
  try {
    const data = ctx.request.body
    check(data.content, 'Params_Lost')
    check(data.articleId, 'Params_Lost')
    check(data.authorId, 'Params_Lost')
    const time = (new Date()).getTime().toString()
    const findArticle = searchArticle(data.articleId)
    check(findArticle, 'No_Such_Article')
    const id = 'c' + findArticle.comments.length.toString().padStart(6, '0')
    const result = {
      id: id,
      create_Ts: time,
      user: data.authorId,
      articleId: data.articleId,
      content: data.content,
      reply: [],
      like: [],
      status: 1
    }
    editArticle({ ...findArticle, comments: [result, ...findArticle.comments] })
    ctx.body = generateOk({ ...findArticle, comments: [result, ...findArticle.comments] })
  } catch (e) {
    catchError(e, ctx)
  }
})

article.post('/reply', async (ctx) => {
  try {
    const data = ctx.request.body
    check(data.content, 'Params_Lost')
    check(data.articleId, 'Params_Lost')
    check(data.authorId, 'Params_Lost')
    check(data.commentId, 'Params_Lost')
    check(data.targetUserId, 'Params_Lost')
    const time = (new Date()).getTime().toString()
    const findArticle = searchArticle(data.articleId)
    check(findArticle, 'No_Such_Article')
    const findComment = findArticle.comments.find(comment => comment.id === data.commentId)
    check(findComment, 'No_Such_Comment')
    const id = 'r' + findComment.reply.length.toString().padStart(6, '0')
    const result = {
      id: id,
      create_Ts: time,
      user: data.authorId,
      articleId: data.articleId,
      commentId: data.commentId,
      content: data.content,
      like: [],
      status: 1,
      targetUserId: data.targetUserId
    }
    findArticle.comments.splice(comment => comment.id === data.commentId, 1, { ...findComment, reply: [...findComment.reply, result] })
    editArticle({ ...findArticle })
    ctx.body = generateOk(findArticle)
  } catch (e) {
    catchError(e, ctx)
  }
})

module.exports = article